#include "directoryscanner.h"
#include <QDir>
#include <QFile>
#include <QDebug>
#include <QFileInfo>
#include <utility>

// 构造函数，初始化统计数据结构
DirectoryScanner::DirectoryScanner(const QString &path, QObject *parent)
    : QThread(parent), m_path(path)
{
    m_stats.name = path;
    m_stats.dir_count = 1;  // 初始化为1，包含自身
    m_stats.file_count = 0;
    m_stats.total_lines = 0;
}

// 析构函数
DirectoryScanner::~DirectoryScanner()
{
    m_abort = true;  // 设置终止标志
    wait();          // 等待线程结束
}

// 线程执行函数
void DirectoryScanner::run() {
    m_updateTimer.start();  // 启动限流计时器
    scanDirectoryRecursive(m_stats);  // 开始递归扫描
    if (!m_abort) {
        // 确保最终发送一次完成信号（即使未达到时间间隔）
        emit filesProcessed(m_totalFilesProcessed.load());
        emit scanningFinished();
    }
}

// 判断是否是源代码文件
bool DirectoryScanner::isSourceFile(const QString &filename)
{
    return filename.endsWith(".c") || filename.endsWith(".h") || filename.endsWith(".cpp");
}

// 统计文件行数
long long DirectoryScanner::countFileLines(const QString &filepath)
{
    if (m_abort) return 0;  // 如果终止请求，直接返回

    QFile file(filepath);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "无法打开文件:" << filepath;
        return 0;
    }

    long long lines = 0;
    while (!file.atEnd()) {
        if (file.readLine().contains('\n')) {
            lines++;
        }
    }
    file.close();
    return lines;
}

// 递归扫描目录
void DirectoryScanner::scanDirectoryRecursive(DirectoryStats &stats) {
    if (m_abort) return;  // 检查终止标志

    QDir dir(stats.name);
    if (!dir.exists()) {
        qWarning() << "目录不存在:" << stats.name;
        return;
    }

    // 获取目录条目（不包括.和..）
    QFileInfoList entries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries);

    // 遍历目录条目
    for (const QFileInfo &entry : std::as_const(entries)) {
        if (m_abort) return;  // 检查终止标志

        if (entry.isFile()) {
            stats.file_count++;  // 文件计数
            m_totalFilesProcessed++;  // 原子递增

            // 限流逻辑：每400ms最多更新一次UI
            if (m_updateTimer.elapsed() >= 400) {
                emit filesProcessed(m_totalFilesProcessed.load());
                m_updateTimer.restart();  // 重置计时器
            }

            // 文件类型统计
            QString suffix = entry.suffix().toLower();
            if (!suffix.isEmpty()) {
                stats.file_types[suffix]++;
            }

            // 如果是源代码文件，统计行数
            if (isSourceFile(entry.fileName())) {
                stats.total_lines += countFileLines(entry.absoluteFilePath());
            }
        }
        // 处理子目录
        else if (entry.isDir()) {
            stats.dir_count++;  // 目录计数

            // 创建子目录统计结构
            DirectoryStats subStats;
            subStats.name = entry.absoluteFilePath();
            subStats.dir_count = 0;
            subStats.file_count = 0;
            subStats.total_lines = 0;
            subStats.file_types.clear();

            // 递归扫描子目录
            scanDirectoryRecursive(subStats);

            // 合并子目录的统计结果
            stats.dir_count += subStats.dir_count;
            stats.file_count += subStats.file_count;
            stats.total_lines += subStats.total_lines;

            // 合并文件类型统计
            for (auto it = subStats.file_types.begin(); it != subStats.file_types.end(); ++it) {
                stats.file_types[it.key()] += it.value();
            }
        }
    }
}